#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

const std::string SEP = "\r\n"; // 以\r\n作为分隔符
// 报文=报头+有效数据
// “len”\r\n"_x_op_y"\r\n

std::string EnCode(std::string json_str) // 添加报头 编码
{
    int json_str_len = json_str.size();
    std::string ret(std::to_string(json_str_len));
    ret += SEP;
    ret += json_str + SEP;
    return ret;
}

std::string DeCode(std::string &buffer) // 解码
{
    auto pos = buffer.find(SEP);
    if (pos == std::string::npos) // 如果没有找到分隔符就直接返回空串
    {
        return "";
    }
    std::string len_str = buffer.substr(0, pos);
    if (len_str.empty())
    {
        return "";
    }
    int packlen = std::stoi(len_str);
    int totallen = len_str.size() + SEP.size() * 2 + packlen; // 一条完整报文应该有的长度
    if (buffer.size() < totallen)                             // 如果buffer长度小于tatallen,说明buffer中一定没有一个完整请求
    {
        return "";
    }
    std::string ret = buffer.substr(pos + SEP.size(), packlen); // 提取出来一条完整的报文
    buffer.erase(0, totallen);                                  // 移除缓冲区中已经读取到的报文
    return ret;
}

class Request
{
public:
    Request()
    {
    }

    Request(int x, int y, int op) : _x(x), _y(y), _op(op)
    {
    }

    void serialize(std::string *out) // 序列化:将一个结构化数据转化成字符串类型数据
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;
        Json::StyledWriter writer;
        *out = writer.write(root);
    }

    bool deserialization(const std::string &in) // 反序列化:将字符串类型数据转化成结构化数据
    {
        Json::Reader reader;
        Json::Value root;
        if (!reader.parse(in, root))
        {
            std::cout << "failed to parse JSON:" << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        return true;
    }

    int get_x() const
    {
        return _x;
    }

    int get_y() const
    {
        return _y;
    }

    int get_op() const
    {
        return _op;
    }

private:
    int _x;
    int _y;
    int _op;
};

class Result
{
public:
    Result()
    {
    }
    Result(int result, char code)
        : _result(result), _code(code)
    {
    }
    void serialize(std::string *out) // 序列化
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        Json::StyledWriter writer;
        *out = writer.write(root);
    }
    bool deserialization(std::string &in) // 反序列化
    {
        Json::Reader reader;
        Json::Value root;
        if (!reader.parse(in, root))
        {
            std::cout << "failed to parse JSON:" << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }

    void set_result(const int &result)
    {
        _result = result;
    }

    void set_code(const char &code)
    {
        _code = code;
    }

    const int get_result() const
    {
        return _result;
    }

    const int get_code() const
    {
        return _code;
    }

private:
    int _result;
    int _code; // 0:success 1:FATAL 2.ERROR ……
};
